package com.zaofan.service;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import com.zaofan.bean.Account;
import com.zaofan.bean.AccountLog;
import com.zaofan.bean.Prepaid;
import com.zaofan.bean.Recharge;
import com.zaofan.constant.PrepaidConstant;
import com.zaofan.constant.StateConstant;
import com.zaofan.constant.TypeConstant;
import com.zaofan.dao.PrepaidDao;
import com.zaofan.exception.ServiceException;
import com.zaofan.utils.C3p0DataSourceUtils;
import com.zaofan.utils.CarNumCreate;
import com.zaofan.utils.JPushUtils;
import com.zaofan.utils.SqlBuilderUtils;
import com.zaofan.utils.WebUtils;

public class PrepaidService {
	private PrepaidDao prepaidDao = new PrepaidDao();
	private AccountService accountService = new AccountService();
	private AccountLogService accountLogService = new AccountLogService();

	public void delete(Prepaid prepaid) {
		prepaidDao.del(prepaid);
	}

	public void add(Prepaid prepaid) {
		prepaid.setAddTime(new Date());
		prepaidDao.add(prepaid);
	}

	public void update(Prepaid prepaid) {
		prepaidDao.update(prepaid);
	}

	public List<Prepaid> findAll(Map<String, Object> params) {
		List<Prepaid> data = prepaidDao.findAll(params);
		if (data == null) {
			data = new ArrayList<>();
		}
		return data;
	}

	public Long count(Map<String, Object> params) {
		return prepaidDao.count(params);
	}

	public Prepaid findById(Integer id) {
		Map<String, Object> params = new HashMap<>();
		params.put("id", id);
		return prepaidDao.findOne(params);
	}

	public List<Prepaid> createPrepaid(int num, BigDecimal money, String name) {
		List<Prepaid> datas = new ArrayList<>();
		if (num <= 0) {
			return datas;
		}
		// Long code = 1000000000001L;
		// Long count = count(null);
		Prepaid prepaid;
		Calendar calendar = Calendar.getInstance();
		for (int i = 1; i <= num; i++) {
			calendar.add(Calendar.SECOND, i);
			prepaid = new Prepaid();
			// prepaid.setCard(calendar.getTimeInMillis() + "" + count + "");
			String cartNum = CarNumCreate.generateMasterCardNumber();
			while (!CarNumCreate.isValidCreditCardNumber(cartNum)) {
				cartNum = CarNumCreate.generateMasterCardNumber();
			}
			prepaid.setCard(cartNum);
			// String md5 = WebUtils.MD5((calendar.getTime() +
			// PrepaidConstant.PREPAID_KEY));
			// String one = md5.substring(PrepaidConstant.POSITION_ONE,
			// PrepaidConstant.POSITION_ONE + 1);
			// String two = md5.substring(PrepaidConstant.POSITION_TWO,
			// PrepaidConstant.POSITION_TWO + 1);
			// String three = md5.substring(PrepaidConstant.POSITION_THREE,
			// PrepaidConstant.POSITION_THREE + 1);
			// String four = md5.substring(PrepaidConstant.POSITION_FOUR,
			// PrepaidConstant.POSITION_FOUR + 1);
			// String five = md5.substring(PrepaidConstant.POSITION_FIVE,
			// PrepaidConstant.POSITION_FIVE + 1);
			// String six = md5.substring(PrepaidConstant.POSITION_SIX,
			// PrepaidConstant.POSITION_SIX + 1);
			String password = "";
			String md5 = WebUtils.MD5((calendar.getTime() + PrepaidConstant.PREPAID_KEY));
			int size = 0;
			while (password.length() < 6 && size < md5.length()) {
				try {
					password += Integer.valueOf(md5.substring(size, size + 1)) + "";

				} catch (Exception e) {
				}
				size++;
			}
			prepaid.setPassword(password);
			prepaid.setMoney(money);
			prepaid.setName(name);
			prepaid.setState(PrepaidConstant.STATE_EFFECTIVE);
			add(prepaid);
			datas.add(prepaid);
		}
		return datas;
	}

	public static void main(String[] args) {
		String cartNum = CarNumCreate.generateMasterCardNumber();
		System.err.println(cartNum);
	}

	public void setPrepaidState(Integer id, Integer state) {
		Prepaid prepaid = new Prepaid();
		prepaid.setId(id);
		prepaid.setState(state);
		update(prepaid);
	}

	public void setPrepaidInUser(String ids) {

	}

	public void recharge(String card, String password, String userId) throws ServiceException, SQLException {
		if (WebUtils.isEmpty(card)) {
			throw new ServiceException("请输入充值卡号!!");
		}
		if (WebUtils.isEmpty(password)) {
			throw new ServiceException("请输入充值卡号密码!!");
		}
		if (WebUtils.isEmpty(userId)) {
			throw new ServiceException("请输入用户信息!!");
		}
		int accounId = 0;
		try {
			accounId = Integer.valueOf(userId);
		} catch (Exception e) {
			throw new ServiceException("用户信息错误!!");
		}
		Account account = accountService.findById(accounId);
		if (account == null) {
			throw new ServiceException("用户信息错误!!");
		}
		Prepaid prepaid = findByCard(card);
		if (prepaid == null) {
			throw new ServiceException("卡号错误,请确认!!");
		}
		if (!prepaid.getPassword().equals(password)) {
			throw new ServiceException("卡密错误,请确认!!");
		}
		if (prepaid.getState() == PrepaidConstant.STATE_USER) {
			throw new ServiceException("对不起,充值卡无法重复充值!!");
		}
		if (prepaid.getState() == PrepaidConstant.STATE_UN_EFFECTIVE) {
			throw new ServiceException("对不起,该充值卡还未生效,如有疑问,请联系我们的客服人员!!");
		}
		System.out.println("即将进入判断");
		System.out.println("即将进入判断"+prepaid.getMoney());

		if (prepaid.getMoney().compareTo(new BigDecimal(11))==0){
			//如果该用户用过11块的

			Connection connection = C3p0DataSourceUtils.getConnection();
			String sql  = "SELECT COUNT(*) FROM accountlog WHERE TYPE = '充值卡充值' AND money=11 AND accountId = "+accounId;
			QueryRunner runner = new QueryRunner();
			Long count = runner.query(connection,sql,new ScalarHandler<Long>());
			if(count.compareTo(new Long(1))>=0){
				System.out.println("用户充值过了11块");
				throw new ServiceException("对不起,11元充值卡只能使用一次!!");
			}

		}
		Connection connection = C3p0DataSourceUtils.getConnection();
		connection.setAutoCommit(false);
		try {
			QueryRunner runner = new QueryRunner();
			prepaid.setState(PrepaidConstant.STATE_USER);
			prepaid.setUseTime(new Date());
			String sql = SqlBuilderUtils.builderUpdateSql(Prepaid.class, prepaid);
			runner.update(connection, sql);
			AccountLog accountLog = new AccountLog();
			accountLog.setAccountId(account.getId());
			accountLog.setAccountMobile(account.getMobile());
			accountLog.setAfterMoney(account.getMoney().add(prepaid.getMoney()));
			accountLog.setBeforeMoney(account.getMoney());
			accountLog.setMoney(prepaid.getMoney());
			accountLog.setAddTime(new Date());
			accountLog.setType(TypeConstant.log_type_prepaid_recharge);
			sql = SqlBuilderUtils.builderInsertSql(AccountLog.class, accountLog);
			runner.update(connection, sql);
			account.setMoney(account.getMoney().add(prepaid.getMoney()));
			sql = SqlBuilderUtils.builderUpdateSql(Account.class, account);
			runner.update(connection, sql);
			// 添加充值记录
			Recharge recharge = new Recharge();
			recharge.setAccountId(account.getId());
			recharge.setAccountMobile(account.getMobile());
			recharge.setAddTime(new Date());
			recharge.setMoney(prepaid.getMoney());
			recharge.setPayAccount("");
			recharge.setPayState(StateConstant.ORDER_PAY_STATE_PAY);
			recharge.setPayTime(new Date());
			recharge.setRechargeNo(WebUtils.getOrderId(accounId));
			recharge.setState(StateConstant.ORDER_STATE_PAY);
			sql = SqlBuilderUtils.builderInsertSql(Recharge.class, recharge);
			runner.update(connection, sql);
			connection.commit();
			JPushUtils.sendPrepaidSuccess(prepaid, account);
		} catch (Exception e) {
			connection.rollback();
		} finally {
			connection.close();
		}
	}

	private Prepaid findByCard(String card) {
		Map<String, Object> params = new HashMap<>();
		params.put("card", card);
		return prepaidDao.findOne(params);
	}

	public void failurePrepaid(String id_s) throws ServiceException {
		Integer id;
		try {
			id = Integer.valueOf(id_s);
		} catch (Exception e) {
			throw new ServiceException("参数错误!!");
		}
		Prepaid prepaid = findById(id);
		if (prepaid == null) {
			throw new ServiceException("卡号错误,请确认!!");
		}
		if (prepaid.getState() == PrepaidConstant.STATE_USER) {
			throw new ServiceException("对不起,充值卡已经被使用了!!");
		}
		prepaid.setState(PrepaidConstant.STATE_UN_EFFECTIVE);
		update(prepaid);
	}
}
